package co.baiku.boot.weibo;

import co.baiku.boot.AjavaerCache;
import co.baiku.boot.cache.service.CacheService;
import co.baiku.boot.common.message.Message;
import co.baiku.boot.common.tools.HttpTools;
import co.baiku.boot.common.tools.StringTools;
import co.baiku.boot.config.WeiboConfig;
import co.baiku.boot.expand.Share;
import co.baiku.boot.message.WeiboAccessToken;
import co.baiku.boot.message.WeiboUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import weibo4j.model.Status;
import weibo4j.model.WeiboException;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

@Component
@ConditionalOnProperty("ajavaer.weibo.appid")
public class Weibo implements InitializingBean {

    private Logger log = LoggerFactory.getLogger(Weibo.class);

    @Resource
    private WeiboConfig weiboConfig;
    private CacheService cacheService;

    private String accessTokenKey(String uid) {
        return StringTools.format(weiboConfig.getCachePrefix() + "token_{0}", uid);
    }

    /**
     * 获得codeurl,微博登录第一步
     *
     * @param redirectUrl 回调url会附带code参数
     * @return
     */
    public Message getCode(String redirectUrl) {
        if (StringTools.isBlank(redirectUrl)) {
            return Message.fail("跳转url不能为空");
        }
        String codeUrl = weiboConfig.getCodeUrl(redirectUrl);
        return Message.result(codeUrl);
    }

    /**
     * 获得accessToken
     *
     * @param redirectUrl
     * @param code
     * @return
     */
    public Message<WeiboAccessToken> accessToken(String redirectUrl, String code) {
        try {
            redirectUrl = URLDecoder.decode(redirectUrl, "utf-8");
            redirectUrl = URLEncoder.encode(redirectUrl, "utf-8");
        } catch (UnsupportedEncodingException e) {
            log.error(e.getMessage(), e);
        }
        String accessTokenUrl = weiboConfig.getAccessTokenUrl(redirectUrl, code);
        Message<WeiboAccessToken> accessTokenMessage = HttpTools.post(accessTokenUrl, new HashMap<>(), WeiboAccessToken.class);
        if (accessTokenMessage.isSuccess()) {
            WeiboAccessToken accessToken = accessTokenMessage.getResult();
            if (accessToken.getSuccess()) {
                cacheService.put(accessTokenKey(accessToken.getUid()), accessToken.getAccess_token(), Integer.parseInt(accessToken.getExpires_in()), TimeUnit.SECONDS);
            }
        }
        return accessTokenMessage;
    }

    /**
     * 通过uid获得已缓存的token,如果获取不到,则需要重新登录
     *
     * @param uid
     * @return
     */
    public Message<String> uidAccessToken(String uid) {
        String accessToken = cacheService.get(accessTokenKey(uid));
        if (StringTools.isNotBlank(accessToken)) {
            return Message.result(accessToken);
        }
        return Message.fail(HttpStatus.NOT_FOUND);
    }

    /**
     * 获取用户信息
     *
     * @param uid
     * @param accessToken
     * @return
     * @see <a href='https://open.weibo.com/wiki/%E8%8E%B7%E5%8F%96%E7%94%A8%E6%88%B7%E5%9F%BA%E6%9C%AC%E4%BF%A1%E6%81%AF'>官方文档</a>
     */
    public Message<WeiboUser> userInfo(String uid, String accessToken) {
        String userInfoUrl = weiboConfig.getUserInfoUrl(accessToken, uid);
        Message<WeiboUser> weiboUserMessage = HttpTools.get(userInfoUrl, WeiboUser.class);
        return weiboUserMessage;
    }

    /**
     * 第三方分享一条链接到微博
     *
     * @param text        用户分享到微博的文本内容，必须做URLencode，内容不超过140个汉字，文本中不能包含“#话题词#”，
     *                    同时文本中必须包含<span style='color:red'>至少一个第三方分享到微博的网页URL</span>，且该URL只能是该第三方（调用方）绑定域下的URL链接，
     *                    绑定域在“我的应用 － 应用信息 － 基本应用信息编辑 － 安全域名”里设置。
     * @param accessToken
     * @param picFile     图片
     * @return
     * @throws IOException
     * @throws WeiboException
     * @see <a href='https://open.weibo.com/wiki/2/statuses/share'>官方文档</a>
     */
    public Message share(String text, String accessToken, File picFile) throws IOException, WeiboException {
        Status uploadStatus = new Share().uploadStatus(accessToken, text, picFile);
        if (uploadStatus.getMid() != null) {
            return Message.success();
        } else {
            return Message.fail("分享失败");
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        cacheService = AjavaerCache.engine(weiboConfig.getCacheEngine());
    }
}
